# _*_ coding:utf-8 _*_
# @Time  : 2022.06.06
# @Author: zizlee
import datetime
import time
import json
import requests
import pandas as pd
import urllib3
urllib3.disable_warnings()


class TradePosition:
    def get_trade_position(self, start_date, variety_en):
        url = 'https://210.13.218.130:9000/v1/datan/quotes/totalVolume/'
        r = requests.get(url, params={'start_date': start_date, 'v': variety_en}, verify=False)
        return r.json()['data']

    def get_rank20_trade(self, start_date, variety_en):
        url = 'https://210.13.218.130:9000/v1/datan/quotes/position/rank20/totalVolume/'
        r = requests.get(url, params={'start_date': start_date, 'v': variety_en}, verify=False)
        # print(r.json())
        return r.json()['data']

    @staticmethod
    def get_quote_start_date(ven, quote_ts=0):
        r = requests.get(f'https://210.13.218.130:9000/v1/datan/quotes/startDate/',
                         params={'v': ven, 'ts': quote_ts},
                         verify=False)
        return r.json()['data']['start_date']

    @staticmethod
    def get_rank_start_date(ven, rank_ts=0):
        r = requests.get(f'https://210.13.218.130:9000/v1/datan/quotes/position/rank20/startDate/',
                         params={'v': ven, 'ts': rank_ts},
                         verify=False)
        return r.json()['data']['start_date']


# 进度打印
def print_progress_bar(current, total, color=35, title=''):  # percent是小数
    percent = round(current/total, 4)
    prefix_progress = '▓' * int(80 * percent)
    leave_progress = '▓' * (80 - int(80 * percent))
    # percent = '%.2f' % (percent * 100)
    print(f'\033[1;{color}m{current}/{total}\033[0m|\033[1;{color}m{prefix_progress}\033[0m{leave_progress} {title}')


# 获取前20净持仓数据
def get_position_data(start_date, end_date=None):
    if not end_date:
        end_date = datetime.datetime.today().strftime('%Y-%m-%d')
    url = f'https://210.13.218.130:9000/v1/datan/quotes/position/rank20/?start_date={start_date}&end_date={end_date}'
    r = requests.get(url, verify=False)
    position_data = r.json()['data']
    print(position_data.keys())
    return position_data['rank_data']


# 处理品种的前20持仓数据到数据库中
def position_handler(indexes, start_date=None):
    total_count = len(indexes)
    if not start_date:
        start_date = datetime.datetime.today().strftime('%Y-%m-%d')
    position_data = get_position_data(start_date=start_date)
    df = pd.DataFrame(position_data)
    df = df[df['quote_date'] >= start_date]
    if df.empty:
        print(f'还没有{start_date}的持仓数据！')
        return
    for i, index_item in enumerate(indexes):
        variety_en = index_item['variety_en']
        value_key = index_item['value_key']
        new_value_df = df[df['variety_en'] == variety_en][['quote_date', value_key]]
        # 重命名类
        save_df = new_value_df.rename(columns={'quote_date': 'datadate', value_key: 'datavalue'})
        if save_df.empty:
            print(f'今日无{index_item["name_zh"]}数据!')
            continue
        save_data_to_server(index_item["id"], save_df.to_dict(orient='records'))
        msg = f'前20持仓指标{index_item["source_id"]},起始日期:{start_date}保存完成.'
        print_progress_bar(current=i + 1, total=total_count, color=35, title=msg)
        time.sleep(0.5)


# 保存数据到指标中
def save_data_to_server(sheet_id, datalist):
    url = f'http://127.0.0.1:8000/v1/datalib/table/update/' if LOCAL else \
        f'https://210.13.218.130:9000/v1/datalib/table/update/'
    body_data = {
        'dataid': sheet_id,
        'row_value': datalist
    }
    try:
        r = requests.post(url, json=body_data, verify=False)
        if r.json()['code'] != 200:
            raise ValueError(f'status_code={r.json()["code"]}')
    except Exception as e:
        if datalist:
            msg = f'保存数据指标 ID={sheet_id}失败了：{e}'
        else:
            msg = f'更新指标 ID={sheet_id} 刷新日期失败了：{e}'
        print(msg)
    else:
        pass


# def brush_index(iid, start_date):
#     url = 'https://210.13.218.130:9000/v1/datalib/table/brush/'
#     r = requests.put(url, json={'index_id': iid, 'start_date': start_date}, verify=False,
#                      headers={
#                          'Ruizy-Token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjIsInJvbGVfY29kZSI6OTk5OSwib3V0X3JvbGUiOjI1NSwiZXhwIjoxNjg5NjM5MzY1LjQ5MTkxMzZ9.K9s2ga01G92ra8dkD_J6aXcgbdA5jS7HFQrouqHDVa8'
#                      })
#     print(r.json())


def update_futures_trade_position_volume():
    with open('R_前20成交_品种成交_持仓.json', 'r', encoding='utf8') as f:
        update_list = json.load(f)

    update_handler = TradePosition()
    today = datetime.datetime.today().strftime('%Y-%m-%d')
    total_count = len(update_list)
    for i, i_item in enumerate(update_list, 1):
        # id = 7657是集运指数的前20名数据
        if i_item['id'] == 7657:
            continue
        if pointers and i_item['source_id'] not in pointers:
            continue
        if i_item['enddate'] == today or i_item['inactive']:
            # print(f'\033[0;32m【{i_item["name"]}({i_item["variety_en"]})】今日配置不更新!\033[0m')
            continue
        start_date = i_item['enddate'] if i_item['enddate'] else i_item['startdate']
        if i_item['flag'] == 'RANK_TRADE':  # 前20名成交
            ret_data = update_handler.get_rank20_trade(start_date=start_date, variety_en=i_item['variety_en'])
            data_list = ret_data['data_list']
            save_data = [{'datadate': row['rank_date'], 'datavalue': row['t_trade']} for row in data_list]
            if len(save_data) < 1:
                end_ts = int(datetime.datetime.strptime(i_item['enddate'], '%Y-%m-%d').timestamp())
                new_start_date = update_handler.get_rank_start_date(ven=i_item['variety_en'], rank_ts=end_ts)
                if not new_start_date:
                    print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})没有新的起始日期!\033[0m')
                    continue
                new_start = (datetime.datetime.strptime(new_start_date, '%Y-%m-%d') - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
                print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})无新数据,设定新的起始日!{new_start} Continue...\033[0m')
                i_item['enddate'] = new_start
                continue
        elif i_item['flag'] == 'TRADE':  # 品种成交量
            ret_data = update_handler.get_trade_position(start_date=start_date, variety_en=i_item['variety_en'])
            data_list = ret_data['data_list']
            save_data = [{'datadate': row['quote_date'], 'datavalue': row['t_trade']} for row in data_list]
            if len(save_data) < 1:
                end_ts = int(datetime.datetime.strptime(i_item['enddate'], '%Y-%m-%d').timestamp())
                new_start_date = update_handler.get_quote_start_date(ven=i_item['variety_en'], quote_ts=end_ts)
                if not new_start_date:
                    print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})没有新的起始日期!\033[0m')
                    continue
                new_start = (datetime.datetime.strptime(new_start_date, '%Y-%m-%d') - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
                print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})无新数据,设定新起始日!{new_start} Continue...\033[0m')
                i_item['enddate'] = new_start
                continue
        elif i_item['flag'] == 'POSITION':  # 品种持仓量
            ret_data = update_handler.get_trade_position(start_date=start_date, variety_en=i_item['variety_en'])
            data_list = ret_data['data_list']
            save_data = [{'datadate': row['quote_date'], 'datavalue': row['t_position']} for row in data_list]
            if len(save_data) < 1:
                end_ts = int(datetime.datetime.strptime(i_item['enddate'], '%Y-%m-%d').timestamp())
                new_start_date = update_handler.get_quote_start_date(ven=i_item['variety_en'], quote_ts=end_ts)
                if not new_start_date:
                    print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})没有新的起始日期!\033[0m')
                    continue
                new_start = (datetime.datetime.strptime(new_start_date, '%Y-%m-%d') - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
                print(f'\033[0;31m【{i_item["name"]}({i_item["variety_en"]})】{start_date}~{i_item["enddate"]}({end_ts})无新数据,设定新起始日!{new_start} Continue...\033[0m')
                i_item['enddate'] = new_start
                continue
        elif i_item['flag'] == 'NET_POSITION':  # 净持仓
            ret_data = update_handler.get_rank20_trade(start_date=start_date, variety_en=i_item['variety_en'])
            data_list = ret_data['data_list']
            for item in data_list:
                item['t_net'] = int(item['t_long_position'] - item['t_short_position'])
            save_data = [{'datadate': row['rank_date'], 'datavalue': row['t_net']} for row in data_list]

            # brush_index(iid=i_item['id'], start_date=i_item['startdate'])
        else:
            continue
        time.sleep(0.5)

        save_data_to_server(i_item['id'], save_data)
        i_item['enddate'] = ret_data['end_date']
        print(f'id={i_item["id"]}【{i_item["name"]}】{start_date}~{i_item["enddate"]}保存完成!{i}/{total_count}')

    with open('R_前20成交_品种成交_持仓.json', 'w', encoding='utf8') as f2:
        json.dump(update_list, f2, indent=2, ensure_ascii=False)


# 主函数
def main():
    with open('R_前20持仓.json', encoding='utf8', mode='r') as fp:
        indexes = json.load(fp)
    print('获取指标数量:{}'.format(len(indexes)))
    if exchange:
        indexes = list(filter(lambda x: x['ex_code'] == exchange, indexes))
    if pointers:
        indexes = list(filter(lambda x: x['source_id'] in pointers, indexes))
    print('待更新数量:{}'.format(len(indexes)))
    position_handler(indexes, start_date=START)

#
# def get_variety():
#     with open('varietyList.json', 'r', encoding='utf8') as vf:
#         v_data = json.load(vf)
#     return {v['variety_en']: v for v in v_data}
#
#
# def add_index_object(index_item):
#     url = "https://210.13.218.130:9000/v1/datalib/table/csm/"
#     headers = {'Ruizy-Token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjIsInJvbGVfY29kZSI6OTk5OSwib3V0X3JvbGUiOjI1NSwiZXhwIjoxNjg5NjM5MzY1LjQ5MTkxMzZ9.K9s2ga01G92ra8dkD_J6aXcgbdA5jS7HFQrouqHDVa8'}
#     r = requests.post(url, json=index_item, headers=headers, verify=False)
#     print(r.json())
#
#
# def get_variety_list():
#     url = "https://210.13.218.130:9000/v1/datan/quotes/totalVolume/?date=2023-7-13"
#     r = requests.get(url, verify=False)
#     data_list = r.json()['data']['data_list'][1:]
#     v_dict = get_variety()
#     for v in data_list:
#         _ov = v_dict.get(v['variety_en'])
#         # 获取开始日期
#         start_date = get_quote_start_date(ven=v['variety_en'])
#         index_obj = {
#             'name_zh': f'期货持仓量:{v_dict.get(v["variety_en"]).get("variety_name")}',
#             'frequency': '日',
#             'unit': '手',
#             'startdate': start_date,
#             'state': 1,
#             'is_open': 1,
#             'variety': _ov['variety_en'],
#             'note': ''
#         }
#         add_index_object(index_obj)
#         time.sleep(1)


if __name__ == '__main__':
    # while 1:
    #     time.sleep(0.3)
    LOCAL = False  # True也没用，ID不符合
    START = '2023-12-12'  # 自定取当前时间
    exchange = 'GFE'
    pointers = []
    main()
    update_futures_trade_position_volume()

    # for i in range(50):
    #     print('次数：', i+1)
    #     update_futures_trade_position_volume()  # 更新持仓成交等数据
    #     time.sleep(1)

